package sf.config;

//import com.alibaba.druid.pool.DruidDataSource;
//import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder;

import com.zaxxer.hikari.HikariDataSource;
import org.smallframework.spring.DaoMapperScannerConfigurer;
import org.smallframework.spring.DaoTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.support.TransactionTemplate;
import sf.database.OrmConfig;
import sf.database.datasource.SimpleRoutingDataSource;
import sf.database.util.OrmValueUtils;
import sf.tools.StringUtils;

import javax.sql.DataSource;

@Configuration
@EnableTransactionManagement(proxyTargetClass = true)
// @EnableConfigurationProperties(GeeQueryConfigProperties.class)
public class DBConfig implements EnvironmentAware {
    private Environment env;

    public static final String sqlType = "sorm.test.sql.type";

    @Override
    public void setEnvironment(Environment env) {
        this.env = env;
    }

//	@Bean(destroyMethod = "close", initMethod = "init")


    @Bean(name = "mysql")
    @ConfigurationProperties("spring.datasource.druid.one")
    @ConditionalOnProperty(name = sqlType, havingValue = "mysql")
    public DataSource dataSourceMysql() {
//        DruidDataSource dds = DruidDataSourceBuilder.create().build();
//        return dds;
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }


    @Bean(name = "mysqlTransactionManager")
    @ConditionalOnProperty(name = sqlType, havingValue = "mysql")
    public PlatformTransactionManager mysqlTransactionManager(@Qualifier("mysql") DataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "oracle")
    @ConfigurationProperties("spring.datasource.hikari.oracle")
    @ConditionalOnProperty(name = sqlType, havingValue = "oracle")
    public DataSource dataSourceOracle() {
//		return DruidDataSourceBuilder.create().build();
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }

    @Bean(name = "sqlserver")
    @ConfigurationProperties("spring.datasource.hikari.sqlserver")
    @ConditionalOnProperty(name = sqlType, havingValue = "sqlserver")
    public DataSource dataSourceSqlserver() {
//		return DruidDataSourceBuilder.create().build();
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }

    @Bean(name = "postgresql")
    @ConfigurationProperties("spring.datasource.druid.postgresql")
    @ConditionalOnProperty(name = sqlType, havingValue = "postgresql")
    public DataSource dataSourcePostgresql() {
//        return DruidDataSourceBuilder.create().build();
		return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }

    @Primary
    @Bean(name = "sqlite")
    @ConfigurationProperties("spring.datasource.hikari.sqlite")
    public DataSource dataSourceSqlite() {
//		return DruidDataSourceBuilder.create().build();
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }

    @Primary
    @Bean(name = "sqliteTransactionManager")
    public PlatformTransactionManager sqliteTransactionManager(@Qualifier("sqlite") DataSource dataSource){
        return new DataSourceTransactionManager(dataSource);
    }

//    @Bean(name = "xaMysql")
//    @ConfigurationProperties(prefix = "spring.jta.atomikos.datasource")
//    @ConditionalOnProperty(name = sqlType, havingValue = "xaMysql")
//    public DataSource dataSourceJTAMyql() {
//        return new AtomikosDataSourceBean();
//    }

    @Primary
    @Bean(name = "reactiveTransactionTemplate")
    public ReactiveTransactionTemplate reactiveTransactionTemplate(TransactionTemplate tt){
        return new ReactiveTransactionTemplate(tt);
    }


    @Bean
    public OrmConfig getOrmConfig(@Autowired(required = false) @Qualifier("xaMysql") DataSource xaMysql,
                                  @Autowired(required = false) @Qualifier("mysql") DataSource mysql,
                                  @Autowired(required = false) @Qualifier("sqlite") DataSource sqlite,
                                  @Autowired(required = false) @Qualifier("postgresql") DataSource postgresql,
                                  @Autowired(required = false) @Qualifier("oracle") DataSource oracle,
                                  @Autowired(required = false) @Qualifier("sqlserver") DataSource sqlserver) {
        SimpleRoutingDataSource routing = new SimpleRoutingDataSource("sqlite",sqlite,null);
//        routing.addDataSource("postgresql", postgresql);
        DaoTemplate dt = new DaoTemplate(routing);
//		DaoTemplate dt = new DaoTemplate(xaMysql);

        OrmConfig config = OrmConfig.getInstance();
        config.setDbClient(dt);
        config.setPackagesToScan(StringUtils.split("db.domain", ","));
        config.setUseTail(true);
        config.setBeanValueType(OrmValueUtils.BeanValueType.reflectasm);
        config.setUseSystemPrint(false);
        config.setShowCallChain(true);
        config.init();
        return config;
    }

    @Bean(name = "daoTemplate")
    public DaoTemplate geDaoTemplate(OrmConfig config) {
        return (DaoTemplate) config.getDbClient();
    }

    @Bean
    public DaoMapperScannerConfigurer daoMapperScannerConfigurer() {
        DaoMapperScannerConfigurer dsc = new DaoMapperScannerConfigurer();
        dsc.setBasePackage("sf.mapper");
        dsc.setDbClient("daoTemplate");
        return dsc;
    }

    @Bean(name = "jdbcTemplate")
    public JdbcTemplate geJdbcTemplate(DataSource ds) {
        JdbcTemplate jt = new JdbcTemplate(ds);
        return jt;
    }


    ///以下为jooq配置
}
